<template>
  <el-dialog
      v-model="dialogVisible"
      title="任务详情"
      width="80%"
      @open="afterOpen"
      @close="beforeClose"
      ref="me"
  >
    <el-form ref="form" label-width="130px" :model="leaveModel" v-if="businessKey" class="businessKey" :disabled="true">
      <el-form-item label="请假开始时间" prop="startTime">
        <el-date-picker
            v-model="leaveModel.startTime"
            type="datetime"
            placeholder="选择日期时间"
            value-format="YYYY-MM-DD hh:mm:ss">
        </el-date-picker>
      </el-form-item>
      <el-form-item label="请假结束时间" prop="endTime">
        <el-date-picker
            v-model="leaveModel.endTime"
            type="datetime"
            placeholder="选择日期时间"
            value-format="YYYY-MM-DD hh:mm:ss"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item label="请假理由" prop="reason">
        <el-input type="textarea" v-model="leaveModel.reason" placeholder="请输入请假理由" :rows="4"></el-input>
      </el-form-item>
      <el-form-item label="请假天数" prop="days">
        <el-input-number v-model="leaveModel.days" />
      </el-form-item>
      <el-form-item label="请假类型" prop="leaveType">
        <el-select v-model="leaveModel.leaveType" placeholder="Select" size="large">
          <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
          >
          </el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <iframe :src="`/flowable/display-custom/displaymodel.html?v=${ts}&processInstanceId=${processInstanceId}&modelType=runtime&processDefinitionId=${definitionId}&historyModelId=${historyProcessInstanceId}`"
            width="100%" height="400"
            frameborder="0" v-if="processInstanceId"></iframe>
    <div style="height: 500px">
      <el-image :src="`/flowableapi/runtime/process-instances/${processInstanceId}/diagram?v=${ts}`"
                fit="cover" v-if="processInstanceId && !historyProcessInstanceId"></el-image>
      <el-image :src="`/flowableapi/repository/process-definitions/${definitionId}/image?v=${ts}`"
                fit="cover" v-else></el-image>
    </div>
    <div class="block">
      <el-timeline>
        <el-timeline-item :timestamp="item.startTime" placement="top" v-for="(item, index) in historyData" :key="index">
          <el-card :class="item.endTime ? 'gray' : 'green'">
            <h4 v-show="item.activityType === 'startEvent'">开始节点</h4>
            <h4 v-show="item.activityType === 'endEvent'">结束节点</h4>
            <h4 v-show="item.activityName">{{item.activityName}}</h4>
            <p v-show="item.activityName" v-html="getInfo(item)"></p>
            <div style="line-height: 3rem;background-color: #7a8daf;border-radius: 2rem">
              <p v-html="item.comments"></p>
            </div>
          </el-card>
        </el-timeline-item>
      </el-timeline>
    </div>
    <div v-show="taskId">
      <el-form :model="commentForm" :rules="commentFormRules" ref="commentFormRef">
        <el-form-item label="意见" prop="content">
          <el-input v-model="commentForm.content" type="textarea" :rows="5"></el-input>
        </el-form-item>
      </el-form>
    </div>
    <div class="btns" v-show="taskId">
      <div class="btn" @click="handleApprove(currentRow)">通过</div>
      <div class="btn" @click="showRefuseDialog">驳回</div>
    </div>
  </el-dialog>
  <el-dialog
      title="请选择驳回节点"
      v-model="refuseDialogVisible"
      width="25%"
      ref="me2">
    <div style="padding: 1.5rem 0;">
      <el-form :model="refuseForm" :rules="rules" ref="myRefuseForm">
        <el-form-item label="驳回节点" prop="startActId">
          <el-select v-model="refuseForm.startActId">
            <el-option
                v-for="item in refuseOptions"
                :key="item.activityId"
                :label="item.activityName"
                :value="item.activityId"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </div>
    <el-button @click="refuseDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="handleRefuse">确 定</el-button>
  </el-dialog>
</template>

<script>
import {reactive, toRefs, getCurrentInstance, watch, ref} from "vue";
import { ElMessageBox, ElMessage } from 'element-plus'
import { ElLoading } from 'element-plus'
export default {
  name: "Task-Detail.vue",
  props: {
    taskId: {
      type: String,
      required: false
    },
    visibleProp: {
      type: Boolean
    },
    historyProcessInstanceId: {
      type: String,
      required: false
    }
  },
  setup(props, context) {
    const {proxy} = getCurrentInstance()
    const beforeClose = () => {
      context.emit('close');
    }
    const commentFormRef = ref(null);
    const me = ref(null);
    const me2 = ref(null);
    const myRefuseForm = ref(null);
    let loadingInstance;
    const state = reactive({
      dialogVisible: false,
      historyData: [],
      leaveModel: {},
      businessKey: '',
      ts: new Date().getTime(),
      processInstanceId: '',
      definitionId: '',
      historyModelId: '',
      refuseDialogVisible: false,
      refuseForm: {
        startActId: ''
      },
      userData: [],
      refuseOptions: [],
      currentTaskDefinitionKey: '',
      page: 1,
      options: [{
        value: '年假',
        label: '年假'
      },{
        value: '事假',
        label: '事假'
      },{
        value: '丧假',
        label: '丧假'
      },{
        value: '病假',
        label: '病假'
      }],
      rules: {
        startActId: [
          {
            required: true,
            message: '请选择节点',
            trigger: 'blur',
          },
        ],
      },
      commentForm: {
        content: ''
      },
      commentFormRules: {
        content: [
          {
            required: true,
            message: '请输入意见',
            trigger: 'blur',
          },
        ],
      },
      comments: []
    })
    watch(() => props.visibleProp, (val, oldVal) => {
       if (val !== oldVal) {
         state.dialogVisible = val;
       }
    })
    const handleRefuse = async () => {
      let validRs = await myRefuseForm.value.validate();
      if (validRs) {
        let rs = await ElMessageBox.confirm('确定驳回?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });
        if (rs === 'confirm') {
          let params = {
            cancelActivityIds: [state.currentTaskDefinitionKey],
            startActivityIds: [state.refuseForm.startActId]
          }
          loadingInstance = ElLoading.service({ target: me2.value.dialogRef })

          await addComment(0);

          proxy.$http.post(`/flowableapi/runtime/process-instances/${state.processInstanceId}/change-state`, params);
          setTimeout(() => {
            loadingInstance.close()
            state.refuseDialogVisible = false;
            ElMessage.success('驳回成功');
            context.emit('handleOk')
            beforeClose();
          }, 6000)
        }
      }
    }
    const queryAllUser = async () =>{
      let res = await proxy.$http.get(`/flowableapi/user/list`)
      if (res.data && res.data.success) {
        state.userData = res.data.data;
      }
    }
    const getInfo = (item) => {
      let assignee = item.assignee;
      if (assignee) {
        let name = state.userData.filter(e => e.id.toString() === assignee)[0].nickname;
        return `<span style="color: red">${name}</span> ${item.endTime ? '执行了此任务' : '需要执行此任务'}`;
      }
      return ''
    }
    const queryHistoryInstanceById = async () => {
      let rs = await proxy.$http.get(`/flowableapi/history/historic-process-instances/${props.historyProcessInstanceId}`);
      state.definitionId = rs.data.processDefinitionId;
      state.ts = new Date().getTime();
      state.businessKey = rs.data.businessKey;
      state.processInstanceId = props.historyProcessInstanceId;
      if (state.businessKey) {
        rs = await proxy.$http.get(`/flowableapi/t_leave_apply/get/${state.businessKey}`);
        state.leaveModel = rs.data.data;
      }
    }
    const queryTaskById = async () => {
      let rs = await proxy.$http.get(`/flowableapi/runtime/tasks/${props.taskId}`);
      if (rs.status === 200) {
        state.processInstanceId = rs.data.processInstanceId;
        state.definitionId = rs.data.processDefinitionId;
        state.currentTaskDefinitionKey = rs.data.taskDefinitionKey;
        state.ts = new Date().getTime();
        let processInstanceUrl = `/flowableapi/runtime/process-instances/${rs.data.processInstanceId}`;
        let rs2 = await proxy.$http.get(processInstanceUrl);
        if (rs2.data.businessKey) {
            // 查询请假详情
            state.businessKey = rs2.data.businessKey;
            let rs3 = await proxy.$http.get(`/flowableapi/t_leave_apply/get/${state.businessKey}`);
            state.leaveModel = rs3.data.data;
        }
      }
    }
    const queryHistoryActivies = async () => {
      let params = {
        order: "asc",
        sort: "startTime",
        size: 100
      }
      let rs = await proxy.$http.post(`/flowableapi/query/historic-activity-instances`,
          {processInstanceId: state.processInstanceId},
          {params}) ;
      state.historyData = rs.data.data.filter(e => e.activityType !== 'sequenceFlow' && e.activityType !== 'exclusiveGateway');
      state.historyData.forEach((e) => {
        if (e.startTime) {
          e.startTime = e.startTime.replace('T', ' ').replace('+', ' ')
        }
      })
      for (let i = 0; i < state.historyData.length; i++) {
        let actData = state.historyData[i];
        let taskId = actData.taskId;
        if (taskId) {
          let taskComments = state.comments.filter(e => e.taskId === taskId).map(e => e.message);
          actData['comments'] = taskComments.join('</br>');
        }
      }
    }
    const afterOpen = async () => {
      loadingInstance = ElLoading.service({ target: me.value.dialogRef })
      await queryAllUser();
      if (props.taskId) {
        await queryTaskById();
      }
      if (props.historyProcessInstanceId) {
        await queryHistoryInstanceById();
      }
      await getComments();
      await queryHistoryActivies();
      loadingInstance.close()
    }
    const getComments = async () => {
      let rs = await proxy.$http.get(`/flowableapi/history/historic-process-instances/${state.processInstanceId}/comments`);
      state.comments = rs.data;
    }
    const handleApprove = async () => {
      let valid = await commentFormRef.value.validate();
      if (!valid) {
          return;
      }
      let rs = await ElMessageBox.confirm('确定审批通过?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      });
      if (rs === 'confirm') {
        let params = {
          action: 'complete'
        }
        loadingInstance = ElLoading.service({ target: me.value.dialogRef })

        await addComment(1);

        proxy.$http.post(`/flowableapi/runtime/tasks/${props.taskId}`, params).then((res) => {
          if (res.status === 200) {
            ElMessage.success('审批通过');
            context.emit('handleOk')
            beforeClose();
          }
          loadingInstance.close()
        })
      }
    }
    const addComment = async (action) => {
      let comment = {
        message: (action === 1 ? `<span style="color:green">同意</span>` : '<span style="color:red">驳回</span>')
            + '<br/>' + state.commentForm.content,
        saveProcessInstanceId: true
      }
      await proxy.$http.post(`/flowableapi/runtime/tasks/${props.taskId}/comments`, comment);
      state.commentForm.content = '';
    }
    const showRefuseDialog = async () => {
      let valid = await commentFormRef.value.validate();
      if (!valid) {
        return;
      }
      loadingInstance = ElLoading.service({ target: me2.value.dialogRef })
      state.refuseDialogVisible = true;
      state.refuseForm.startActId = '';
      let params = {
        order: "desc",
        sort: "startTime"
      }
      let rs = await proxy.$http.post(`/flowableapi/query/historic-activity-instances`,
          {processInstanceId: state.processInstanceId, activityType: 'userTask', finished: true},
          {params}) ;
      if (rs.data.data.length > 0) {
        state.refuseOptions = [];
        for (let i = 0; i < rs.data.data.length; i++) {
          let activityId = rs.data.data[i].activityId;
          let activityName = rs.data.data[i].activityName;
          let exist = state.refuseOptions.filter(e => e.activityId === activityId).length > 0;
          if (!exist && activityId !== state.currentTaskDefinitionKey) {
            state.refuseOptions.push({
              activityId,
              activityName
            })
          }
        }
      } else {
        ElMessage.warning('当前节点不允许驳回');
        return
      }
      loadingInstance.close()
    }
    return {
      ...toRefs(state),
      afterOpen,
      handleApprove,
      showRefuseDialog,
      handleRefuse,
      beforeClose,
      getInfo,
      me,
      me2,
      myRefuseForm,
      commentFormRef
    }
  }
}
</script>

<style scoped lang="less">
.green {
  background-color: #2ca02c;
}
.gray {
  background-color: #b1b489;
}

.btns {
  width: 100%;
  display: flex;
  .btn {
    flex: 1;
    line-height: 4rem;
    color: white;
    cursor: pointer;
    border-radius: .5rem;
    font-size: 1.5rem;
  }
  .btn:nth-child(1) {
    background-color: yellowgreen;
  }
  .btn:nth-child(2) {
    background-color: red;
  }
}
</style>
